home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / mtools-3.000 / mtools-3 / mtools-3.0 / codepage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-08  |  4.3 KB  |  211 lines

  1. #include "sysincludes.h"
  2. #include "mtools.h"
  3. #include "codepage.h"
  4.  
  5.  
  6. Codepage_t *Codepage=0;
  7. char *mstoupper=0;
  8.  
  9.  
  10. #undef WORD
  11. #define WORD(x,y) (file[(x)+2*(y)] + (file[(x)+1+2*(y)] << 8))
  12.  
  13. #define COUNTRY(x) WORD(25+(x)*14, 1)
  14. #define CODEPAGE(x) WORD(25+(x)*14, 2)
  15. #define DATA(x) WORD(25+(x)*14, 5)
  16. #define CTYINFO(x) WORD(DATA(x), 3)
  17. #define CTYINFOCP(x) WORD(CTYINFO(x), 6)
  18. #define UCASE(x) WORD(DATA(x), 11)
  19. #define UCASEBYTE file[ucase+10+j*8+k]
  20.  
  21. #define NBVARS(x) WORD(DATA(x), 0)
  22. #define VARID(x,y) WORD(DATA(x), y*4+2)
  23. #define VARVAL(x,y) WORD(DATA(x), y*4+3)
  24.  
  25. static void bad_country_file(void)
  26. {
  27.     fprintf(stderr,"Corrupted country.sys file\n");
  28.     cleanup_and_exit(1);
  29. }
  30.  
  31. static void not_found(int country_found, int country, int codepage)
  32. {
  33.     if(!country_found)
  34.         fprintf(stderr,"Country code %03d not supported\n",
  35.             country);
  36.     else    
  37.         fprintf(stderr,"Country/codepage combo %03d/%d not supported\n",
  38.             country, codepage);
  39.     cleanup_and_exit(1);
  40. }
  41.  
  42.  
  43. static short get_variable(unsigned char *file, int i, int id)
  44. {
  45.     int j;
  46.  
  47.     for(j=0; j < NBVARS(i); j++)
  48.         if(VARID(i,j) == id)
  49.             return VARVAL(i,j);
  50.     return 0;
  51. }
  52.  
  53.  
  54. static void set_toupper_from_builtin(int country, int *codepage)
  55. {
  56.     country_t *p;
  57.     int country_found = 0;
  58.  
  59.     if(mstoupper)
  60.         return;
  61.     for(p = countries; p->country; p++) {
  62.         if(p->country == country) {
  63.             country_found = 1;
  64.             if(!*codepage)
  65.                 *codepage = p->default_codepage;
  66.             if (p->codepage == *codepage) {
  67.                 mstoupper = (char *) toucase[p->to_upper];
  68.                 return;
  69.             }
  70.         }
  71.     }
  72.     not_found(country_found, country, *codepage);
  73. }
  74.  
  75.  
  76. static void load_toupper(int country, int *codepage, char *filename)
  77. {
  78.     int fd, filesize;
  79.     unsigned char file[65536];
  80.     unsigned short ucase=0, records;
  81.     int i;
  82.     int country_found = 0;
  83.  
  84.     if(!filename) {
  85.         set_toupper_from_builtin(country, codepage);
  86.         return;
  87.     }
  88.  
  89.     fd = open(filename, O_RDONLY);
  90.     if(fd < 0) {
  91.         perror("open country.sys");
  92.         cleanup_and_exit(1);
  93.     }
  94.  
  95.     /* load country.sys */
  96.     filesize=read(fd, (char *) file, 65536);
  97.     if(filesize < 0) {
  98.         perror("Read country.sys\n");
  99.         cleanup_and_exit(1);
  100.     }
  101.  
  102.     if(strcmp((char *)file, "\377COUNTRY"))
  103.         bad_country_file();
  104.  
  105.     records = WORD(23,0);    
  106.  
  107.     /* second pass: locate translation table */
  108.     for(i=0; i<records; i++) {
  109.         if(country == COUNTRY(i)) {
  110.             country_found = 1;
  111.             if(!*codepage)
  112.                 *codepage = get_variable(file, i, 1);
  113.             if(mstoupper)
  114.                 continue;
  115.             if(*codepage == CODEPAGE(i)) {
  116.                 ucase = get_variable(file, i, 4);
  117.                 if(!ucase) {
  118.                     fprintf(stderr,
  119.                         "No translation table for this"
  120.                         "country and code page\n");
  121.                     cleanup_and_exit(1);
  122.                 }
  123.                 if(strncmp((char*)file+ucase+1, "UCASE", 5) &&
  124.                    strncmp((char*)file+ucase+1, "FUCASE", 6))
  125.                     bad_country_file();
  126.                 mstoupper = (char *) toucase[0];
  127.                 memcpy(mstoupper, file + ucase + 10, 128);
  128.                 return;
  129.             }
  130.         }
  131.     }
  132.     not_found(country_found, country, *codepage);
  133. }
  134.  
  135. static void set_codepage(int nr)
  136. {
  137.     if(Codepage)
  138.         return;
  139.     for(Codepage = codepages; Codepage->nr; Codepage++)
  140.         if(Codepage->nr == nr)
  141.             return;
  142.     fprintf(stderr,"Unknown code page %d\n", nr);
  143.     cleanup_and_exit(1);
  144.  
  145. }
  146.  
  147.  
  148. static void syntax(void)
  149. {
  150.     fprintf(stderr,"Syntax error in COUNTRY environmental variable\n");
  151.     fprintf(stderr,"Usage: export COUNTRY=countrycode[,[codepage][,filename]]\n");
  152.     cleanup_and_exit(1);
  153. }
  154.  
  155. void init_codepage(void)
  156. {
  157.     char *country, *file;
  158.     int country_prefix;
  159.     int codepage;
  160.  
  161.     file = 0;
  162.     country=country_string;
  163.     if(!country) {
  164.         codepage = 850;
  165.         country_prefix = 41; /* Switzerland */
  166.     } else {
  167.         file = 0;
  168.         codepage = 0;
  169.         country_prefix = strtoul(country, &country, 10);
  170.         if(!country_prefix)
  171.             syntax();
  172.         if(*country==',') {
  173.             country++;
  174.             codepage = strtoul(country, &country,10);
  175.             if(*country==',') {
  176.                 file = country+1;
  177.             } else if (*country)
  178.                 syntax();
  179.         } else if(*country)
  180.             syntax();
  181.     }    
  182.  
  183.     load_toupper(country_prefix, &codepage, file);
  184.     set_codepage(codepage);
  185. }
  186.  
  187. unsigned char to_dos(unsigned char c)
  188. {
  189.     int oc;
  190.  
  191.     if(c < 0x80)
  192.         return c;
  193.     for(oc = 0 ; oc < 128; oc++) {
  194.         if(c == Codepage->tounix[oc])
  195.             return oc | 0x80;
  196.     }
  197.     return '_';
  198. }
  199.  
  200.  
  201. void to_unix(char *a, int n)
  202. {
  203.     for( ; *a && n >= 0; n--, a++) {
  204.         /* special case, 0xE5 */
  205.         if(*a == 0x05)
  206.             *a = (char) 0xe5;
  207.         if(*a & 0x80)
  208.             *a = (char) Codepage->tounix[(*a) & 0x7f];
  209.     }
  210. }
  211.